package com.adjaisd.scarecrow.controller;


import com.adjaisd.scarecrow.common.result.Result;
import com.adjaisd.scarecrow.common.utils.jwt.JwtUtils;
import com.adjaisd.scarecrow.common.utils.mqtt.EmqClient;
import com.adjaisd.scarecrow.entity.Device;
import com.adjaisd.scarecrow.entity.Quota;
import com.adjaisd.scarecrow.service.AlarmService;
import com.adjaisd.scarecrow.service.DeviceService;
import com.adjaisd.scarecrow.service.QuotaService;
import com.adjaisd.scarecrow.vo.DeviceQuotaVO;
import com.adjaisd.scarecrow.vo.Pager;
import com.adjaisd.scarecrow.vo.QuotaAlarmVO;
import io.jsonwebtoken.Claims;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author adjaisd
 * @since 2022-03-24
 */
@RestController
@RequestMapping("/quota")
public class QuotaController {

    @Autowired
    EmqClient emqClient;

    @Autowired
    QuotaService quotaService;

    @ApiOperation(value = "获取单个指标")
    @RequestMapping(value = "/get", method = RequestMethod.POST)
    @ResponseBody
    public Result getSingleQuota(HttpServletRequest request, @RequestBody Map<String, String> map) {
        String token = request.getHeader("X-token");
        Claims claims = JwtUtils.getMembers(token);
        Long userId = Long.parseLong(claims.get("id").toString());

        try {
            String quotaId = map.get("quotaId");
            Quota quota = quotaService.getById(quotaId);
            if (quota == null || !quota.getOwnerId().equals(userId) || quota.getCreateTime() == 0L)
                return Result.fail().code(400).message("不存在该指标");
            return Result.succ().code(200).data("quota", quota).message("获取指标成功");
        } catch (Exception e) {
            System.out.println(e);
            return Result.succ().code(400).message("参数错误");
        }
    }

    @ApiOperation(value = "获取指标列表")
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    @ResponseBody
    public Result getQuotaList(HttpServletRequest request) {
        String token = request.getHeader("X-token");
        Claims claims = JwtUtils.getMembers(token);
        Long userId = Long.parseLong(claims.get("id").toString());

        List<Quota> quotas = quotaService.getQuotaListByUID(userId);
        return Result.succ().code(200).data("quotaList", quotas).message("查询指标成功");
    }

    @ApiOperation(value = "分页查询所有设备指标")
    @ApiImplicitParam(name = "map", required = true, value = "分页信息", paramType = "body", dataType = "json")
    @RequestMapping(value = "/device-quota-page", method = RequestMethod.POST)
    public Result findDeviceQuotaPage(HttpServletRequest request, @RequestBody Map<String, String> map) {
        String token = request.getHeader("X-token");
        Claims claims = JwtUtils.getMembers(token);
        long userId = Long.parseLong(claims.get("id").toString());

        String number = "";
        String tag = "";
        int state = -1; // 默认状态无限制：在线且开启，离线或关闭
        long page = 1L, pageSize = 10L;
        try {
            if (map.containsKey("page")) page = Long.parseLong(map.get("page"));
            if (map.containsKey("pageSize")) pageSize = Long.parseLong(map.get("pageSize"));
            if (map.containsKey("number")) {
                number = map.get("number");
                Device device = deviceService.getDeviceByNumber(Long.valueOf(number));
                if (!device.getOwnerId().equals(userId))    // 检测是否拥有者
                    return Result.fail().code(400).message("没有该设备");
            }
            if (map.containsKey("tag")) tag = map.get("tag");
            if (map.containsKey("state")) state = Integer.parseInt(map.get("state"));
            Pager<DeviceQuotaVO> pager = quotaService.queryDeviceQuotaPage(userId, page, pageSize, number, tag, state);
            return Result.succ().code(200).data("pager", pager).message("分页查询设备成功");
        } catch (Exception e) {
            System.out.println(e);
            return Result.fail().code(400).message("参数错误");
        }
    }

    // 分页查询设备指标
    @ApiOperation(value = "分页查询指标报警")
    @ApiImplicitParam(name = "map", required = true, value = "分页信息", paramType = "body", dataType = "json")
    @RequestMapping(value = "/quota-alarm-page", method = RequestMethod.POST)
    public Result findQuotaAlarmPage(HttpServletRequest request, @RequestBody Map<String, String> map) {
        String token = request.getHeader("X-token");
        Claims claims = JwtUtils.getMembers(token);
        long userId = Long.parseLong(claims.get("id").toString());

        String number = "";
        String name = "";
        long page = 1L, pageSize = 10L;
        try {
            if (map.containsKey("page")) page = Long.parseLong(map.get("page"));
            if (map.containsKey("pageSize")) pageSize = Long.parseLong(map.get("pageSize"));
            if (map.containsKey("number")) {
                number = map.get("number");
                Device device = deviceService.getDeviceByNumber(Long.valueOf(number));
                if (!device.getOwnerId().equals(userId))    // 检测是否拥有者
                    return Result.fail().code(400).message("没有该设备");
            }
            if (map.containsKey("name")) name = map.get("name");
            Pager<QuotaAlarmVO> pager = quotaService.queryQuotaAlarmPage(userId, page, pageSize, name, number);
            return Result.succ().code(200).data("pager", pager).message("分页查询设备成功");
        } catch (Exception e) {
            System.out.println(e);
            return Result.fail().code(400).message("参数错误");
        }
    }

    @Autowired
    DeviceService deviceService;

    @ApiOperation(value = "添加指标")
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    @ResponseBody
    public Result addQuota(HttpServletRequest request, @RequestBody Map<String, String> quotaForm) {
        String token = request.getHeader("X-token");
        Claims claims = JwtUtils.getMembers(token);
        Long userId = Long.parseLong(claims.get("id").toString());

        try {
            String name = quotaForm.get("name");
            Long number = Long.parseLong(quotaForm.get("number"));
            String subject = quotaForm.get("subject");
            String valueKey = quotaForm.get("valueKey");
            String valueType = quotaForm.get("valueType");

            String unit = quotaForm.get("unit");
            String webhook = quotaForm.get("webhook");
            String reference = quotaForm.get("reference");
            Long time = new Date().getTime();
            Quota quota = new Quota(null, name, unit, subject, valueKey, valueType, number, webhook, reference, time, userId);
            System.out.println("quota = " + quota);

            // 检查是否存在设备
            Device device = deviceService.getDeviceByNumber(number);
            if (device == null || device.getBindTime() == 0L)
                return Result.fail().code(400).message("不存在该设备");
            else if (!device.getOwnerId().equals(userId))
                return Result.fail().code(400).message("不存在该设备");

            Quota q = quotaService.getQuota(number, name, subject, valueKey, valueType, userId);
            if (q != null) {    // 指标是否存在
                if (q.getCreateTime() != 0L)
                    return Result.fail().code(400).message("已存在该指标");
                quota.setId(q.getId());
                quotaService.updateById(quota);
            } else {
                try {
                    emqClient.subscribe("$queue/" + subject);
                } catch (MqttException e) {
                    e.printStackTrace();
                    return Result.fail().code(400).message("订阅失败");
                }
                quotaService.addQuota(quota);
                Quota t = quotaService.getQuota(number, name, subject, valueKey, valueType, userId);
                quota.setId(t.getId());
            }
            return Result.succ().code(200).data("quota", quota).message("添加指标成功");
        } catch (Exception e) {
            System.out.println(e);
            return Result.fail().code(50015).message("缺少必要参数");
        }
    }

    @Autowired
    AlarmService alarmService;

    @ApiOperation(value = "删除指标")
    @ApiImplicitParam(name = "quotaForm", required = true, value = "指标信息表", paramType = "body", dataType = "json")
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    @ResponseBody
    public Result delQuota(HttpServletRequest request, @RequestBody Map<String, String> quotaForm) throws MqttException {
        String token = request.getHeader("X-token");
        Claims claims = JwtUtils.getMembers(token);
        Long userId = Long.parseLong(claims.get("id").toString());

        try {
            String name = quotaForm.get("name");
            String number = quotaForm.get("number");
            String valueKey = quotaForm.get("valueKey");
            String valueType = quotaForm.get("valueType");

            String subject = quotaForm.get("subject");
            Quota quota = quotaService.getQuota(Long.valueOf(number), name, subject, valueKey, valueType, userId);
            if (quota != null) {
                if (quota.getCreateTime() == 0L)
                    return Result.fail().code(400).message("不存在该指标");

                // 检测指标下是否存在告警
                if (alarmService.existAlarmByQID(quota.getId()))
                    return Result.fail().code(401).message("指标下存在报警");

                if (quotaService.delQuota(Long.valueOf(number), name, subject, valueKey, valueType, userId)) {
                    if (!quotaService.existSubject(subject))
                        emqClient.unsubscribe("$queue/" + subject);
                    return Result.succ().code(200).message("删除成功");
                } else return Result.fail().code(400).message("删除失败");
            } else return Result.fail().code(400).message("不存在该指标");
        } catch (Exception e) {
            System.out.println(e);
            return Result.fail().code(50015).message("缺少必要参数");
        }
    }

    @ApiOperation(value = "更新指标")
    @ApiImplicitParam(name = "quotaForm", required = true, value = "指标信息表", paramType = "body", dataType = "json")
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    @ResponseBody
    public Result updateQuota(HttpServletRequest request, @RequestBody Map<String, String> quotaForm) {
        String token = request.getHeader("X-token");
        Claims claims = JwtUtils.getMembers(token);
        Long userId = Long.parseLong(claims.get("id").toString());

        try {
            // 不可变
            Long number = Long.parseLong(quotaForm.get("number"));
            String valueKey = quotaForm.get("valueKey");
            String valueType = quotaForm.get("valueType");
            String name = quotaForm.get("name");
            String subject = quotaForm.get("subject");

            // 可变
            String unit = quotaForm.get("unit");
            String webhook = quotaForm.get("webhook");
            String reference = quotaForm.get("reference");

            Quota quota = quotaService.getQuota(number, name, subject, valueKey, valueType, userId);
            if (quota != null) {
                if (quota.getCreateTime() == 0L)
                    return Result.fail().code(400).message("不存在该指标");
                quota.setUnit(unit);
                quota.setWebhook(webhook);
                quota.setReference(reference);
                if (quotaService.updateById(quota))
                    return Result.succ().code(200).message("更新指标成功");
                else
                    return Result.fail().code(500).message("更新失败");
            } else return Result.fail().code(400).message("不存在该指标");
        } catch (Exception e) {
            System.out.println(e);
            return Result.fail().code(50015).message("缺少必要参数");
        }
    }

}
